package com.yenroc.ho.transaction;

import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import com.yenroc.ho.netty.NettyClient;
import com.yenroc.ho.netty.TkMessageVo;
import com.yenroc.ho.netty.enums.GlobalTransactionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author： heyanpeng
 * @date： 2021/7/27
 */
@Component
public class GlobalTransactionManager {

    private final static Logger log = LoggerFactory.getLogger(GlobalTransactionManager.class);

    private static NettyClient nettyClient;

    private static ThreadLocal<GlobalTransactionInfo> transactionInfoThreadLocal = new ThreadLocal<>();

    // 存放本地事务信息
    private static Map<String, List<GlobalTransactionInfo>> transactionInfoMap = new HashMap<>();

    @Autowired
    public void setNettyClient(NettyClient nettyClient){
        GlobalTransactionManager.nettyClient = nettyClient;
    }

    public static GlobalTransactionInfo createTransaction(){
        GlobalTransactionInfo transactionInfo = getCurrent();
        // 当前全局线程,在本服务还没有事务,则创建一个事务组事务
        List<GlobalTransactionInfo> globalTransactionInfos = transactionInfoMap.get(transactionInfo.getGroupId());
        if (globalTransactionInfos == null || globalTransactionInfos.size() == 0) {
            globalTransactionInfos = new ArrayList<>();
            transactionInfoMap.put(transactionInfo.getGroupId(), globalTransactionInfos);
        }
        globalTransactionInfos.add(transactionInfo);
        // 通知事务中心创建事务
        sendCreateTransaction(transactionInfo);

        return transactionInfo;
    }

    public static List<GlobalTransactionInfo> getTransactionInfo(String groupId){
        return transactionInfoMap.get(groupId);
    }

    public static GlobalTransactionInfo getCurrent(){
        if (transactionInfoThreadLocal.get() == null) {
            String groupId = Thread.currentThread().getName();
            transactionInfoThreadLocal.set(new GlobalTransactionInfo(groupId));
        }
        return transactionInfoThreadLocal.get();
    }

    /**
     * 通知事务中心 本地事务的事务结果
     * @param transaction
     */
    public static void sendTransactionResult(GlobalTransactionInfo transaction, GlobalTransactionType type){
        TkMessageVo tkMessageVo = new TkMessageVo();
        tkMessageVo.setGroupId(transaction.getGroupId());
        tkMessageVo.setTransactionId(transaction.getTransactionId());
        tkMessageVo.setTransactionType(type);
        tkMessageVo.setMessage("事务完成通知");
        nettyClient.send(tkMessageVo);
    }

    /**
     * 通知 事务中心 进行事务创建
     * @param transaction
     */
    private static void sendCreateTransaction(GlobalTransactionInfo transaction){
        TkMessageVo tkMessageVo = new TkMessageVo();
        tkMessageVo.setGroupId(transaction.getGroupId());
        tkMessageVo.setTransactionId(transaction.getTransactionId());
        tkMessageVo.setMessage("通知事务中心创建事务");
        nettyClient.send(tkMessageVo);
    }
}
